package com.hspedu.sqlsession;

import com.hspedu.config.Function;
import com.hspedu.config.MapperBean;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

import java.io.InputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Iterator;

public class HspConfiguration {
    private static ClassLoader loader = ClassLoader.getSystemClassLoader();

    public Connection build(String resource) throws DocumentException, ClassNotFoundException {
        InputStream inputStream = loader.getResourceAsStream(resource);
        SAXReader saxReader = new SAXReader();
        Document document = saxReader.read(inputStream);
        Element root = document.getRootElement();
        return evalDataSource(root);
    }

    //获取数据库连接
    private Connection evalDataSource(Element node) throws ClassNotFoundException, RuntimeException {
        if(!"database".equals(node.getName())){
            throw new RuntimeException("root should be <database>");
        }
        String driverClassName = null;
        String url = null;
        String username = null;
        String password = null;

        //获取属性节点
        for(Object item:node.elements("property")){
            Element i = (Element) item;
            String value = (String) getValue(i);
            String name = i.attributeValue("name");
            if(name==null || value == null){
                throw new RuntimeException("[database]: <property> should contain name and value");
            }
            //赋值
            switch(name){
                case "url":
                    url=value;
                    break;
                case "username":
                    username=value;
                    break;
                case "password":
                    password = value;
                    break;
                case "driverClassName":
                    driverClassName = value;
                    break;
                default:
                    throw new RuntimeException("[database]: <property> unknown name");
            }
        }
        Class.forName(driverClassName);
        Connection connection = null;
        try{
            connection = DriverManager.getConnection(url,username,password);
        }catch (SQLException e){
            e.printStackTrace();
        }
        return connection;
    }

    //获取property属性的值 ,如果有value值,则读取 没有设置value,则读取内容
    private String getValue(Element node) {
        //<name>Tom</name>
        //node.getText()返回 "Tom"
        return node.hasContent() ? node.getText() : node.attributeValue("value");
    }

    @SuppressWarnings("rawtypes")
    public MapperBean readMapper(String path){
        MapperBean mapper = new MapperBean();

        try{
            InputStream inputStream = loader.getResourceAsStream(path);
            SAXReader reader = new SAXReader();
            Document document = reader.read(inputStream);
            Element root = document.getRootElement();

            //把mapper节点的nameSpace值存为接口名
            mapper.setInterfaceName(root.attributeValue("namespace").trim());

            //用来存储方法的list
            ArrayList<Function> list = new ArrayList<>();
            //遍历根节点下所有子节点
            for (Iterator rootIter = root.elementIterator();rootIter.hasNext();){
                Function fun = new Function();//用来存储一条方法的信息
                Element e = (Element) rootIter.next();
                String sqltype = e.getName().trim();
                String funcName = e.attributeValue("id").trim();
                String sql = e.getText().trim();
                String resultType = e.attributeValue("resultType").trim();
                fun.setSqltype(sqltype);
                fun.setFuncName(funcName);
                Object newInstance = null;
                try{
                    newInstance = Class.forName(resultType).newInstance();
                }catch (InstantiationException e1){
                    e1.printStackTrace();
                }catch (IllegalAccessException e1){
                    e1.printStackTrace();
                }catch(ClassNotFoundException e1){
                    e1.printStackTrace();
                }
                fun.setResultType(newInstance);
                fun.setSql(sql);
                list.add(fun);
            }
            mapper.setList(list);
        }catch (DocumentException e){
            e.printStackTrace();
        }
        return mapper;
    }


}
